<?php

namespace addons\booking\model;

use think\Model;
use addons\booking\model\Order;
use addons\booking\model\SubscribeLog;
use think\Queue;

class TemplateMsg extends Model
{

    // 表名
    protected $name = 'booking_template_msg';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = false;

    // 追加属性
    protected $append = [];


    public static function getTplIds()
    {
        return self::where('switch', 1)->column('tpl_id');
    }

    //获取发送模板消息的数据
    public static function getSendHouseData()
    {
        if (!SubscribeLog::where('status', 0)->find()) {
            return;
        }

        $config = get_addon_config('booking');
        $now_time = time();
        $time = $now_time + (int)$config['critical_timeout'];
        $templateArr = self::where('switch', 1)->column('ident,tpl_id');
        $holdData = [];
        $subscribeIds = [];
        //房间入住前，房间过期前，订单失效前
        $order = Order::field('o.orderid,o.amount,o.coupon_amount,o.checkin_time,o.leave_time,o.status,o.createtime ordercreatetime,t.openid,t.openname,h.name house_name,h.interval_time,s.tpl_id,s.id subscribe_id')
            ->alias('o')
            ->join('third t', "t.user_id=o.user_id and t.apptype='miniapp'")
            ->join('booking_house h', 'h.id=o.source_id and o.type=0')
            ->join('booking_subscribe_log s', 's.orderid=o.orderid and s.status=0')
            ->where('o.status', 'in', ['created', 'paid', 'toshopay', 'checkined'])
            ->select();

        //循环判断可发送的消息
        foreach ($order as $item) {

            if (empty($item['openid'])) {
                continue;
            }

            $data = [
                'orderid'         => $item['orderid'],
                'ordercreatetime' => date('Y-m-d H:i:s', $item['ordercreatetime']),
                'openid'          => $item['openid'],
                'nickname'        => $item['openname'],
                'house_name'      => $item['house_name'],
                'amount'          => $item['amount'],
                'coupon_amount'   => $item['coupon_amount'],
                'checkin_time'    => date('Y-m-d', $item['checkin_time']),
                'leave_time'      => date('Y-m-d', $item['leave_time']),
                'subscribe_id'    => $item['subscribe_id']
            ];
            $identArr = [];
            //房间入住前
            if ($item['status'] == 'paid' && $item['checkin_time'] > $now_time && $item['checkin_time'] < $time) {
                $identArr[] = 1;
            }
            //房间过期前
            if ($item['status'] == 'checkined' && $item['leave_time'] > $now_time && $item['leave_time'] < $time) {
                $identArr[] = 2;
            }
            //订单失效前【线上付】
            $o_time = $config['order_timeout'] + $item['ordercreatetime'];
            if ($item['status'] == 'created' && $o_time > $now_time && $o_time < $time) {
                $identArr[] = 0;
            }
            //订单失效前【到店付】
            if ($item['status'] == 'toshopay' && $item['interval_time'] > date('H:i:s') && (strtotime($item['interval_time']) - time() < 3600)) {
                $identArr[] = 0;
            }

            foreach ($identArr as $key => $value) {
                if (isset($templateArr[$value]) && $templateArr[$value] == $item['tpl_id']) {
                    $subscribeIds[] = $data['subscribe_id'];
                    $holdData[] = array_merge($data, ['ident' => $value]);
                }
            }
        }
        // 封装数据
        self::assembleData($holdData);
        // 变更状态
        SubscribeLog::where('id', 'in', $subscribeIds)->update(['status' => 1]);
    }

    //组装模板数据
    public static function assembleData($holdData)
    {
        $pushList = [];
        $tplArr = self::where('switch', 1)->column('*', 'ident');

        foreach ($holdData as $index => $holdDatum) {
            $data = [];
            $tpl = isset($tplArr[$holdDatum['ident']]) ? $tplArr[$holdDatum['ident']] : [];
            if (!$tpl) {
                continue;
            }
            $tpl['content'] = is_array($tpl['content']) ? $tpl['content'] : (array)json_decode($tpl['content'], true);
            foreach ($tpl['content'] as $item) {
                $value = str_replace('.DATA}}', '', str_replace('{{', '', $item['value']));
                if ($value) {
                    $data[$value] = [
                        'value' => $item['key'] != 'diy_text' ? ($item['def_val'] ? $item['def_val'] : $holdDatum[$item['key']]) : $item['def_val']
                    ];
                }
            }
            $pushData = [
                'touser'      => $holdDatum['openid'],
                'template_id' => $tpl['tpl_id'],
                'page'        => $tpl['page'],
                'data'        => $data
            ];
            $pushList[] = $pushData;
        }
        $config = get_addon_config('booking');
        try {
            if ($config['sendnoticemode'] == 'queue') {
                if (extension_loaded('redis') && class_exists('\think\Queue')) {
                    //使用队列发送
                    foreach ($pushList as $index => $item) {
                        Queue::push('addons\booking\controller\queue\Subscribe', $item, 'bookingSubscribeQueue');
                    }
                }
            } elseif ($config['sendnoticemode'] == 'async') {
                //异步并发发送
                (new \addons\booking\library\Wechat\Service)->subscribeMessageSendMultiple($pushList);
            }
        } catch (\Exception $e) {
        }
    }
}
